/**
 * 自定义call实现
 * @param context   上下文this对象
 * @param args      动态参数
 */

Function.prototype.myCall = function(context, ...arg) {
  // 判断调用的对象是否是函数 context是this的指向
  if (typeof this !== 'function') {
    throw new TypeError('Error');
  }
  // 其实也可以用到arguments 这样就不用写形参...args
  // 判断context,如果为null 或者dundefined 则等于window
  // context = (typeof context === 'object' ? context : window);
  context = context || window;
  // 防止覆盖掉原有属性
  const key = Symbol();
  // 将调用的函数作为对象的临时方法，要用中括号起来
  // 如果这么写context.key 是将key作为属性放在对象中。
  context[key] = this;
  // 调用这个对象中的函数，，此时的函数的this 指向这个对象
  const result = context[key](...arg);
  // 将Symbol属性删除
  delete context[key];
  // 返回函数的结果
  return result;
};

// 测试一下
var value = 2;

var obj = {
  value: 1,
  key: function() {
    console.log('wzy');
  }
}

function bar(name, age) {
  console.log(this.value);
  return {
    value: this.value,
    name: name,
    age: age
  }
}

// 浏览器中指向window

console.log('myCall:');
console.log(bar.myCall(null));// 2
console.log(bar.myCall(obj, 'kevin', 18));
console.log(obj);

console.log('call:');
console.log(bar.call(null));// 2
console.log(bar.call(obj, 'kevin', 18));